package com.kgis.fm.common.manager
{

	import com.kgis.flexutil.MruCache;
	import com.kgis.fm.flex.model.constant.LayerTypeConstant;
	import com.kgis.fm.flex.model.manager.FmMetaData;
	import com.kgis.fm.flex.model.metadata.Attribute;
	import com.kgis.fm.flex.model.metadata.Connectionship;
	import com.kgis.fm.flex.model.metadata.Feature;
	import com.kgis.fm.flex.model.metadata.GeneralParameter;
	import com.kgis.fm.flex.model.metadata.Ownership;
	import com.kgis.fm.flex.model.metadata.RelationshipMapping;
	import com.kgis.fm.flex.model.term.BusinessLabel;
	import com.kgis.fm.flex.model.term.BusinessLabelRule;
	import com.kgis.fm.flex.model.term.BusinessStyleRule;
	import com.kgis.fm.flex.model.term.BusinessTextStyle;
	import com.kgis.fm.flex.model.term.LayerParameter;
	import com.kgis.fm.flex.model.term.LegendEntry;
	import com.kgis.fm.flex.model.term.LegendEntryDefinition;
	
	import flash.utils.Dictionary;
	
	import flashx.textLayout.elements.BreakElement;
	
	import mx.collections.ArrayCollection;
	
	import r1.deval.rt.ForInCond;

	/**
	 * 缓存图层元数据
	 * @author zhxiaomiao
	 * */
	/**
	 * 
	 * @author yhe
	 */
	/**
	 * 
	 * @author yhe
	 */
	/**
	 * 
	 * @author yhe
	 */
	/**
	 * 
	 * @author yhe
	 */
	public class MetaDataManager
	{

		private var _metaDataCache:MruCache=new MruCache(20);
		public static var KEY_KGM_METAData:String="kgm_metadata";
		private static var _instance:MetaDataManager=null;

		public static function getInstance():MetaDataManager
		{
			if (!_instance)
			{
				_instance=new MetaDataManager();
			}
			return _instance;
		}

		public function MetaDataManager()
		{
			if (_instance)
			{
				throw new Error('MetaDataManager is singleton');
			}
		}

		public function addMetaData(key:String, metaData:FmMetaData):void
		{
			_metaDataCache.add(key, metaData);
		}

		public function getMetaData(key:String):Object
		{
			return _metaDataCache.getValue(key);
		}

		/**
		 *get legendentry by id
		 * */
		public static function getLegendEntryById(legendEntryId:Number):LegendEntry
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (metaData == null && metaData.legendEntryList == null)
			{
				return null;
			}
			for each (var entry:LegendEntry in metaData.legendEntryList)
			{
				if (entry.leno == legendEntryId || entry.leno == -legendEntryId)
				{
					return entry;
				}
			}
			return null;
		}

		public static function getLegendEntryByFnoCno(fno:int, cno:int):ArrayCollection
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (metaData == null && metaData.legendEntryList == null)
			{
				return null;
			}
			var legendEntrys:ArrayCollection=new ArrayCollection();
			for each (var entry:LegendEntry in metaData.legendEntryList)
			{
				if (entry.fno == fno && entry.cno == cno)
				{
					if(!legendEntrys.contains(entry)){
						legendEntrys.addItem(entry);
					}
				}
			}
			return legendEntrys;
		}

		/**
		 *get legendentry by label legendentry id
		 * */
		public static function getLegendEntryByLabelEntryId(legendEntryId:Number):LegendEntry
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (metaData == null && metaData.legendEntryList == null)
			{
				return null;
			}
			for each (var entry:LegendEntry in metaData.legendEntryList)
			{
				if (entry.autoLabelLeno == legendEntryId)
				{
					return entry;
				}
			}
			return null;
		}

		/**
		 * get legendentry defination by legend id and legendentry id
		 * */
		public static function getLegendEntryDefByEntryId(legendId:Number, legendEntryId:Number):LegendEntryDefinition
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (metaData == null && metaData.legendEntryDefList == null)
			{
				return null;
			}
			for each (var entryDef:LegendEntryDefinition in metaData.legendEntryDefList)
			{
				if (entryDef.lno == legendId && entryDef.leno == legendEntryId)
				{
					return entryDef;
				}
			}
			return null;
		}

		/**
		 * get stylerule by legend id and legendentry id
		 * */
		public static function getStyleRuleByLegendEntryId(legendEntryId:Number):ArrayCollection
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (metaData == null && metaData.styleRuleList == null)
			{
				return null;
			}
			var styleRules:ArrayCollection=new ArrayCollection();
			var legendEntry:LegendEntry=getLegendEntryById(legendEntryId);
			for each (var styleRule:BusinessStyleRule in metaData.styleRuleList)
			{
				if (styleRule.srno == legendEntry.srno)
				{
					styleRules.addItem(styleRule);
				}
			}
			return styleRules;
		}

		/**
		 * get style by id
		 * */
		public static function getGeometryStyleById(styleId:Number, styleType:Number):Object
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (metaData == null)
			{
				return null;
			}
			var styleList:ArrayCollection=null;
			switch (styleType)
			{
				case LayerTypeConstant.LAYERTYPE_POINT:
					styleList=metaData.pointStyleList;
					break;
				case LayerTypeConstant.LAYERTYPE_POLYLINE:
					styleList=metaData.polylineStyleList;
					break;
				case LayerTypeConstant.LAYERTYPE_POLYGON:
					styleList=metaData.polygonStyleList;
					break;
				case LayerTypeConstant.LAYERTYPE_TEXT:
					styleList=metaData.labelStyleList;
			}
			if (styleList == null)
			{
				return null;
			}
			for each (var style:Object in styleList)
			{
				if (style.sno == styleId)
				{
					return style;
				}
			}
			return null;
		}

		/**
		 * get labelrule by lrno
		 * */
		public static function getLabelRuleByLegendEntryId(lrno:Number):ArrayCollection
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (metaData == null && metaData.labelRuleList == null)
			{
				return null;
			}
			var labelRules:ArrayCollection=new ArrayCollection();
			for each (var labelRule:BusinessLabelRule in metaData.labelRuleList)
			{
				if (labelRule.lrno == lrno)
				{
					labelRules.addItem(labelRule);
				}
			}
			return labelRules;
		}

		/**
		 * get label by lfno(label formate id)
		 * */
		public static function getLabelById(lfno:Number):BusinessLabel
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (metaData.labelList == null)
			{
				return null;
			}
			for each (var label:BusinessLabel in metaData.labelList)
			{
				if (label.lfno == lfno)
				{
					return label;
				}
			}
			return null;
		}

		public static function getLayerParameterById(layerId:Number):LayerParameter
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			for each (var layerPara:LayerParameter in metaData.layerParameterList)
			{
				if (layerPara.layerId == layerId)
				{
					return layerPara;
				}
			}
			return null;
		}

		public static function getLayerParameterByType(layerType:Number):LayerParameter
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			for each (var layerPara:LayerParameter in metaData.layerParameterList)
			{
				if (layerPara.layerType == layerType)
				{
					return layerPara;
				}
			}
			return null;
		}

		/**
		 *与entityTypeId有关系的relationIds
		 * */
		public static function getRelationshipLayerIds(layerId:Number):ArrayCollection
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			//get fno cno by layerid from kgm_legendentry
			var legendEntry:LegendEntry=getLegendEntryById(layerId);
			var fno:int=legendEntry.fno;
			var cno:int=legendEntry.cno;
			//finding the relationship by fno and cno
			var relationsLayerIds:ArrayCollection=new ArrayCollection();

			if (metaData.relationshipMappingList == null)
			{
				return null;
			}
			var legendEntrys:ArrayCollection;
			for each (var relationMapping:RelationshipMapping in metaData.relationshipMappingList)
			{
				if (relationMapping.fno == fno && relationMapping.cno == cno)
				{
					switch (relationMapping.type)
					{
						case RelationshipMapping.TYPE_NODEEDGE_CONNECTIVITY:
							var conns:ArrayCollection=getConnectionLayerByFnoCno(fno, cno);
							for each (var conn:Connectionship in conns)
							{
								legendEntrys=getLegendEntryByFnoCno(conn.clientFno, conn.clientCno);
								if (legendEntrys)
								{
									for each(var legendEntry:LegendEntry in legendEntrys){
										if(!relationsLayerIds.contains(legendEntry.leno)){
											relationsLayerIds.addItem(legendEntry.leno);
										}
									}
									
								}
							}
							break;
						case RelationshipMapping.TYPE_PRAENT_CHILID:
							var parentsChildShips:ArrayCollection=getParentChildshipByFnoCno(fno, cno);
							for each (var parentShip:Ownership in parentsChildShips)
							{
								legendEntrys=getLegendEntryByFnoCno(parentShip.sourceFno, parentShip.sourceCno);
								if (legendEntrys)
								{
									for each(var legendEntry:LegendEntry in legendEntrys){
										if(!relationsLayerIds.contains(legendEntry.leno)){
											relationsLayerIds.addItem(legendEntry.leno);
										}
									}
								}
							}
							break;
						case RelationshipMapping.TYPE_CHILID_PRAENT:
							var childParentShips:ArrayCollection=getChildParentshipByFnoCno(fno, cno);
							for each (var childShip:Ownership in childParentShips)
							{
								legendEntrys=getLegendEntryByFnoCno(childShip.ownerFno, childShip.ownerCno);
								if (legendEntrys)
								{
									for each(var legendEntry:LegendEntry in legendEntrys){
										if(!relationsLayerIds.contains(legendEntry.leno)){
											relationsLayerIds.addItem(legendEntry.leno);
										}
									}
								}
								break;
							}
					}
				}
			}
			return relationsLayerIds;
		}

		public static function getConnectionLayerByFnoCno(fno:int, cno:int):ArrayCollection
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (!metaData.connectionshipList)
			{
				return null;
			}
			var connections:ArrayCollection=new ArrayCollection();
			for each (var connection:Connectionship in metaData.connectionshipList)
			{
				if (connection.sourceFno == fno && connection.sourceCno == cno)
				{
					connections.addItem(connection);
				}
			}
			return connections;
		}

		/**
		 * @param fno
		 *
		 * @param cno
		 * */
		public static function getParentChildshipByFnoCno(fno:int, cno:int):ArrayCollection
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (!metaData.ownershipList)
			{
				return null;
			}
			var ownerships:ArrayCollection=new ArrayCollection();
			for each (var ownership:Ownership in metaData.ownershipList)
			{
				if (ownership.ownerFno == fno && ownership.ownerCno == cno)
				{
					ownerships.addItem(ownership);
				}
			}
			return ownerships;
		}

		public static function getChildParentshipByFnoCno(fno:int, cno:int):ArrayCollection
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (!metaData.ownershipList)
			{
				return null;
			}
			var ownerships:ArrayCollection=new ArrayCollection();
			for each (var ownership:Ownership in metaData.ownershipList)
			{
				if (ownership.sourceFno == fno && ownership.sourceCno == cno)
				{
					ownerships.addItem(ownership);
				}
			}
			return ownerships;
		}

		
		/**
		 * 通过FNO得到设备名称
		 * @param fno  设备FNO
		 * @return 设备名称
		 */
		public static function getFeatureByFno(fno:int):Feature
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if(!metaData.featureList)
			{
				return null;
			}
			for each(var fea:Feature in metaData.featureList)
			{
				if(fea.fno==fno)
				{
					return fea;
					break;
				}
			}
			
			return null;
		}
		
		public static function getPrimarygeographicLayerByFno(fno:int):ArrayCollection{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			var feature:Feature=getFeatureByFno(fno);
			return getLegendEntryByFnoCno(fno,feature.primaryGeoGraphicCno);
		}
		
		/**
		 * 通过CNO得到属性字段
		 * */
		public static function getAttributeByCno(cno:Number):ArrayCollection
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (metaData == null && metaData.attributeList == null)
			{
				return null;
			}
			var attrList:ArrayCollection=new ArrayCollection();
			for each (var attr:Attribute in metaData.attributeList)
			{
				if (attr.cno== cno)
				{
					attrList.addItem(attr);
				}
			}
			return attrList;
		}
		
		
		/**
		 * 通过NAME得到GeneralParameter
		 * */
		public static function getGeneralParameterByName(name:String):String
		{
			var metaData:FmMetaData=MetaDataManager.getInstance().getMetaData(MetaDataManager.KEY_KGM_METAData) as FmMetaData;
			if (metaData == null && metaData.generalParameterList == null)
			{
				return null;
			}
			
			for each (var attr:GeneralParameter in metaData.generalParameterList)
			{
				if (attr.name== name)
				{
					return attr.value;
				}
			}
			
			return null;
		}
	}
}